package com.esd.verifyCode.demo1;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.imageio.ImageIO;

public class AutoDiscern2 {
	// private int[] num = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	private static int[] num = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };

	private ArrayList<int[]> list = new ArrayList<>(9);
	private int black = -16777216;
	private int x = 6, y = 3, w = 9, h = 13, z = 11;

	public AutoDiscern2() {
		list.add(s0);
		list.add(s1);
		list.add(s2);
		list.add(s3);
		list.add(s4);
		list.add(s5);
		list.add(s6);
		list.add(s7);
		list.add(s8);
		list.add(s9);

		list.add(s10);
		list.add(s11);
		list.add(s12);
		list.add(s13);
		list.add(s14);
		list.add(s15);
		list.add(s16);
		list.add(s17);
		list.add(s18);
		list.add(s19);

	}

	private int[] proc(BufferedImage bufferedImage) {
		int w = 7;
		int h = 11;
		int[] pixels = new int[w * h];
		int[] s = getRGB(bufferedImage, 0, 0, w, h, pixels);

		for (int m = 0; m < s.length; m++) {
			if (s[m] == black) {
				s[m] = 0;
			} else {
				s[m] = -1;
			}
		}
		return s;
	}

	// 截取各位数为识别数
	public String char1(Integer code) {
		String c = String.valueOf(code);
		if (c.length() > 1) {
			String ss = String.valueOf(c.charAt(1));
			return ss;
		}
		return String.valueOf(code);
	}

	// 获取所有切片的文件集合
	public byte[] cutList(byte[] be) {
		List<byte[]> list = new ArrayList<byte[]>();
		int w = 7, h = 11;
		for (int my = 0; my < 17; my++) {
			for (int mx = 0; mx < 25; mx++) {
				// String fn = "img_d5/src/" + mx + "_" + my + ".bmp";
				byte[] b = cut(be, mx, my, w, h);
				list.add(b);
			}
		}

		int tmp = 0;
		int index = 0;
		List<Sort> listSort = new ArrayList<Sort>();
		for (int n = 0; n < list.size(); n++) {
			byte[] b = (byte[]) list.get(n);
			ByteArrayInputStream in = new ByteArrayInputStream(b); // 将b作为输入流；
			BufferedImage bufferedImage = null;
			try {
				bufferedImage = ImageIO.read(in);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			int target = 0;
			int[] src = proc(bufferedImage);
			for (int k = 0; k < src.length; k++) {// 获取特征像素的数量
				if (src[k] == 0) {
					target++;
				}
			}

			if (target == 0) {
				continue;
			}

			Sort sort = new Sort();
			sort.setIndex(target);
			// sort.setPath(fnPath);
			sort.setBytes(b);
			listSort.add(sort);

			if (target > tmp) {
				tmp = target;
				index = n;
			}

		}

		Collections.sort(listSort, new Comparator<Object>() {
			@Override
			public int compare(Object o1, Object o2) {
				return new Integer(((Sort) o1).getIndex()).compareTo(new Integer(((Sort) o2).getIndex()));

			}

		});

		Collections.reverse(listSort);
		List<Sort> ll = new ArrayList<Sort>();
		Sort intSort = listSort.get(0);
		ll.add(intSort);
		for (int s = 1; s < listSort.size(); s++) {
			Sort sort = (Sort) listSort.get(s);
			if (sort.getIndex() == intSort.getIndex()) {
				ll.add(sort);
			}
		}

		// 筛选出相同像素点靠左上的一个
		for (Iterator iterator = ll.iterator(); iterator.hasNext();) {
			Sort sort = (Sort) iterator.next();
			ByteArrayInputStream in = new ByteArrayInputStream(sort.getBytes()); // 将b作为输入流；
			BufferedImage bufferedImage = null;
			try {
				bufferedImage = ImageIO.read(in);
			} catch (IOException e) {
				e.printStackTrace();
			}
			int[] src = proc(bufferedImage);
			// 判断x轴是否有黑点
			boolean xx = false;
			for (int x = 0; x < 8; x++) {
				if (src[x] == 0) {
					xx = true;
				}
			}
			// 判断Y
			boolean yy = false;
			for (int y = 0; y < 72; y = y + 8) {
				if (src[y] == 0) {
					yy = true;
				}
			}

			if (xx == true && yy == true) {
				return sort.getBytes();
			}
		}

		return list.get(index);
		// return bmp;
	}

	// 获取所有切片的文件集合
	public String cutList(String bmp) {
		List<String> list = new ArrayList<>();
		int w = 7, h = 11;
		for (int my = 0; my < 17; my++) {
			for (int mx = 0; mx < 25; mx++) {
				String fn = "img_d5/src/" + mx + "_" + my + ".bmp";
				cut(bmp, fn, mx, my, w, h);
				list.add(fn);
			}
		}
		int tmp = 0;
		int index = 0;
		List<Sort> listSort = new ArrayList<Sort>();
		for (int n = 0; n < list.size(); n++) {
			String fnPath = (String) list.get(n);
			BufferedImage bufferedImage = null;
			try {
				bufferedImage = ImageIO.read(new File(fnPath));
			} catch (IOException e) {
				e.printStackTrace();
			}
			int target = 0;
			int[] src = proc(bufferedImage);
			for (int k = 0; k < src.length; k++) {// 获取特征像素的数量
				if (src[k] == 0) {
					target++;
				}
			}

			if (target == 0) {
				continue;
			}

			Sort sort = new Sort();
			sort.setIndex(target);
			sort.setPath(fnPath);
			listSort.add(sort);

			if (target > tmp) {
				tmp = target;
				index = n;
			}

		}

		Collections.sort(listSort, new Comparator<Object>() {
			@Override
			public int compare(Object o1, Object o2) {
				return new Integer(((Sort) o1).getIndex()).compareTo(new Integer(((Sort) o2).getIndex()));

			}

		});

		Collections.reverse(listSort);
		List<Sort> ll = new ArrayList<Sort>();
		Sort intSort = listSort.get(0);
		ll.add(intSort);
		for (int s = 1; s < listSort.size(); s++) {
			Sort sort = (Sort) listSort.get(s);
			if (sort.getIndex() == intSort.getIndex()) {
				ll.add(sort);
			}
		}

		// 筛选出相同像素点靠左上的一个
		for (Iterator iterator = ll.iterator(); iterator.hasNext();) {
			Sort sort = (Sort) iterator.next();
			BufferedImage bufferedImage = null;
			try {
				bufferedImage = ImageIO.read(new File(sort.getPath()));
			} catch (IOException e) {
				e.printStackTrace();
			}
			int[] src = proc(bufferedImage);
			// 判断x轴是否有黑点
			boolean xx = false;
			for (int x = 0; x < 8; x++) {
				if (src[x] == 0) {
					xx = true;
				}
			}
			// 判断Y
			boolean yy = false;
			for (int y = 0; y < 72; y = y + 8) {
				if (src[y] == 0) {
					yy = true;
				}
			}

			if (xx == true && yy == true) {
				return sort.getPath();
			}
		}

		return list.get(index);
		// return bmp;
	}

	// 一张图片的识别结果
	public String disCutList(byte[] be) {
		byte[] ff = cutList(be);
		Map<Integer, Integer> map = discern(ff);
		Integer key = 0;
		Integer value = null;
		Integer tmp = 0;
		for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
			Entry<Integer, Integer> entry = (Entry<Integer, Integer>) iterator.next();
			key = entry.getKey().intValue();
			value = entry.getValue();
			if (key > tmp) {
				tmp = key;
			}
		}
		value = map.get(tmp);

		return String.valueOf(char1(value));

	}

	// Map<Double, Integer> map = discern(fn);
	// if (map != null) {
	// Double key = 0D;
	// for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();)
	// {
	// Entry<Double, Integer> entry = (Entry<Double, Integer>) iterator.next();
	// if (entry.getKey() > key) {
	// key = entry.getKey();
	// }
	// }
	// Integer code = map.get(key);
	//
	// return String.valueOf(char1(code));
	// }
	public String discernPic(BufferedImage bi, int dw) {
		int x = 1, y = 1, w = 31, h = 28, z = 31;
		BiImage2 biImage = new BiImage2();
		try {
			biImage.initialize(bi);
			byte[] temp = biImage.monochrome();
			// for (int i = 0; i < 4; i++) {
			// cut("img_d4/temp_black_white.bmp", "img_d4/tmp" + i + ".bmp", x +
			// z * i, y, w, h);
			// }

			// StringBuffer sb = new StringBuffer();
			// for (int i = 0; i < 4; i++) {
			// byte[] bytes = cut(temp, x + z * i, y, w, h);
			// int s = discern(bytes);
			// if (String.valueOf(s).length() > 1) {
			// sb.append((char) s);
			// } else {
			// sb.append(s);
			// }
			// // sb.append(s);
			// }
			// return sb.toString();
			String a = null, b = null, c = null, d = null;
			// imagesrc = "img_d5/temp_black_white.bmp";
			if (dw == 1 || dw == 0) {
				// cut(imagesrc, "img_d5/tmp1.bmp", x + z * 0, y, w, h);
				byte[] temp1 = cut(temp, x + z * 0, y, w, h);
				// a = disCutList("img_d5/tmp1.bmp");
				a = disCutList(temp1);
			}
			if (dw == 2 || dw == 0) {
				// cut(imagesrc, "img_d5/tmp2.bmp", (x + z * 1) - 1, y, w, h);
				byte[] temp2 = cut(temp, (x + z * 1) - 1, y, w, h);
				// b = disCutList("img_d5/tmp2.bmp");
				b = disCutList(temp2);
			}
			if (dw == 3 || dw == 0) {
				// cut(imagesrc, "img_d5/tmp3.bmp", (x + z * 2) - 1, y, w, h);
				byte[] temp3 = cut(temp, (x + z * 2) - 1, y, w, h);
				c = disCutList(temp3);
			}
			if (dw == 4 || dw == 0) {
				// cut(imagesrc, "img_d5/tmp4.bmp", (x + z * 3) - 1, y, w, h);
				byte[] temp4 = cut(temp, (x + z * 3) - 1, y, w, h);
				d = disCutList(temp4);
			}
			StringBuffer sb = new StringBuffer();
			sb.append(a).append(b).append(c).append(d);
			return sb.toString();
			// int s1 = discern(btemp1);
			// int s2 = discern(bTemp2);
			// int s3 = discern(bTemp3);
			// int s4 = discern(bTemp4);
			// int s1 = discern("tmp1.jpg");
			// int s2 = discern("tmp2.jpg");
			// int s3 = discern("tmp3.jpg");
			// int s4 = discern("tmp4.jpg");
			// StringBuffer sb = new StringBuffer();
			// sb.append(s1).append(s2).append(s3).append(s4);
			// return sb.toString();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;

	}

	public Map<Integer, Integer> discern(String fnPath) {
		// if (!fnPath.endsWith("17_5.bmp")) {
		// return null;
		// }
		Map<Integer, Integer> ret = new HashMap<Integer, Integer>();
		BufferedImage bufferedImage = null;
		try {
			bufferedImage = ImageIO.read(new File(fnPath));
		} catch (IOException e) {
			e.printStackTrace();
		}
		int dValue = 0;
		int value = -1;
		int target = 0;
		int[] src = proc(bufferedImage);
		for (int k = 0; k < src.length; k++) {// 获取特征像素的数量
			if (src[k] == 0) {
				target++;
			}
		}
		if (target == 0) { // 如果要比对的资源没有特征像素直接返回。
			return null;
		}
		// ==================================================================================================================
		List listInfo = new ArrayList<>();
		for (int l = 0; l < list.size(); l++) { // 开始循环比对
			int tmp = 0;
			int tmp1 = 0;
			int[] it = (int[]) list.get(l);
			int templet = 0;
			for (int k = 0; k < it.length; k++) {// 获取当前比对模板的特征像素点。
				if (it[k] == 0) {
					templet++;
				}
			}
			Double trb = ((Double.valueOf(target) / Double.valueOf(templet)) * 100);
			// if (trb < 100) {// 目标特征点必须高于模板特征点
			// // 如果目档特征点小于60%可能是空白或是不足以判断的图片，直接跳过。
			// continue;
			// }
			for (int i = 0; i < src.length; i++) {// 比对特征点。获取特征点的符合数量。
				if (src[i] == it[i]) {
					tmp++;
				}
				if (src[i] == it[i] && it[i] == 0) {
					tmp1++;
				}
			}
			if (tmp == 0) { // 如果像素点等于0 直接重新循环
				continue;
			}
			tmp += tmp1;
			if (tmp > dValue) {// 保存比率最高的
				dValue = tmp;
				value = l;
			}
			// }
			tmp = 0;
			templet = 0;

		}
		if (value == -1) {// 如果没有识别成功返还空
			return null;
		}

		ret.put(dValue, num[value]);// 否则返回百分比
		return ret;
	}

	// public Map<Double, Integer> discern8(int l, int[] src, int target, String
	// fnPath) {
	// Map<Double, Integer> ret = new HashMap<Double, Integer>();
	// Double dValue = 0D;
	// int value = -1;
	// int resemble = 0;
	// int tmp = 0;
	// int[] it = (int[]) list.get(l);
	// resemble = 0;
	// for (int k = 0; k < it.length; k++) {// 获取当前比对模板的特征像素点。
	// if (it[k] == 0) {
	// resemble++;
	// }
	// }
	// Double trb = ((Double.valueOf(target) / Double.valueOf(resemble)) * 100);
	// if (trb > 90) {// 目标特征点必须高于模板特征点
	// for (int i = 0; i < src.length; i++) {// 比对特征点。获取特征点的符合数量。
	// if (src[i] == it[i]) {
	// tmp++;
	// }
	// }
	// if (tmp != 0) {// 符合点大于0的情况下判断识别情况
	// if (tmp == resemble) {// 如果识别的和特征相同，匹配成功。
	// ret.put(100D, num[l]);
	// return ret;
	// }
	// Double bl = ((Double.valueOf(tmp) / Double.valueOf(resemble)) * 100);//
	// 获取识别占比
	// if (bl > dValue) {// 保存比率最高的
	// dValue = bl;
	// value = l;
	// }
	// }
	// tmp = 0;
	// resemble = 0;
	// }
	// ret.put(dValue, num[value]);
	// return ret;
	// }

	public Map<Integer, Integer> discern(byte[] b) {
		// if (!fnPath.endsWith("17_5.bmp")) {
		// return null;
		// }
		Map<Integer, Integer> ret = new HashMap<Integer, Integer>();
		ByteArrayInputStream in = new ByteArrayInputStream(b); // 将b作为输入流；
		BufferedImage bufferedImage = null;
		try {
			bufferedImage = ImageIO.read(in);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		int dValue = 0;
		int value = -1;
		int target = 0;
		int[] src = proc(bufferedImage);
		for (int k = 0; k < src.length; k++) {// 获取特征像素的数量
			if (src[k] == 0) {
				target++;
			}
		}
		if (target == 0) { // 如果要比对的资源没有特征像素直接返回。
			return null;
		}
		// ==================================================================================================================
		List listInfo = new ArrayList<>();
		for (int l = 0; l < list.size(); l++) { // 开始循环比对
			int tmp = 0;
			int tmp1 = 0;
			int[] it = (int[]) list.get(l);
			int templet = 0;
			for (int k = 0; k < it.length; k++) {// 获取当前比对模板的特征像素点。
				if (it[k] == 0) {
					templet++;
				}
			}
			Double trb = ((Double.valueOf(target) / Double.valueOf(templet)) * 100);
			// if (trb < 100) {// 目标特征点必须高于模板特征点
			// // 如果目档特征点小于60%可能是空白或是不足以判断的图片，直接跳过。
			// continue;
			// }
			for (int i = 0; i < src.length; i++) {// 比对特征点。获取特征点的符合数量。
				if (src[i] == it[i]) {
					tmp++;
				}
				if (src[i] == it[i] && it[i] == 0) {
					tmp1++;
				}
			}
			if (tmp == 0) { // 如果像素点等于0 直接重新循环
				continue;
			}
			tmp += tmp1;
			if (tmp > dValue) {// 保存比率最高的
				dValue = tmp;
				value = l;
			}
			// }
			tmp = 0;
			templet = 0;

		}
		if (value == -1) {// 如果没有识别成功返还空
			return null;
		}

		ret.put(dValue, num[value]);// 否则返回百分比
		return ret;
	}

	public int[] getRGB(BufferedImage image, int x, int y, int width, int height, int[] pixels) {

		int type = image.getType();
		if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB)
			return (int[]) image.getRaster().getDataElements(x, y, width, height, pixels);
		return image.getRGB(x, y, width, height, pixels, 0, width);
	}

	/**
	 * 图像切割(按指定起点坐标和宽高切割)
	 * 
	 * @param srcImageFile
	 *            源图像地址
	 * @param result
	 *            切片后的图像地址
	 * @param x
	 *            目标切片起点坐标X
	 * @param y
	 *            目标切片起点坐标Y
	 * @param width
	 *            目标切片宽度
	 * @param height
	 *            目标切片高度
	 */
	public void cut(String srcImageFile, String result, int x, int y, int width, int height) {
		try {
			// 读取源图像
			BufferedImage bi = ImageIO.read(new File(srcImageFile));
			int srcHeight = bi.getHeight(); // 源图宽度
			int srcWidth = bi.getWidth(); // 源图高度
			if (srcWidth > 0 && srcHeight > 0) {
				Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
				// 四个参数分别为图像起点坐标和宽高
				// 即: CropImageFilter(int x,int y,int width,int height)
				ImageFilter cropFilter = new CropImageFilter(x, y, width, height);
				Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));
				BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
				Graphics g = tag.getGraphics();
				g.drawImage(img, 0, 0, width, height, null); // 绘制切割后的图
				g.dispose();
				// 输出为文件
				ImageIO.write(tag, "BMP", new File(result));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public byte[] cut(byte[] buf, int x, int y, int width, int height) {
		try {
			// 读取源图像
			BufferedImage bi = ImageIO.read(new ByteArrayInputStream(buf));
			int srcHeight = bi.getHeight(); // 源图宽度
			int srcWidth = bi.getWidth(); // 源图高度
			if (srcWidth > 0 && srcHeight > 0) {
				Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
				// 四个参数分别为图像起点坐标和宽高
				// 即: CropImageFilter(int x,int y,int width,int height)
				ImageFilter cropFilter = new CropImageFilter(x, y, width, height);
				Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));
				BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
				Graphics g = tag.getGraphics();
				g.drawImage(img, 0, 0, width, height, null); // 绘制切割后的图
				g.dispose();
				// 输出为文件
				ByteArrayOutputStream os = new ByteArrayOutputStream();
				ImageIO.write(tag, "BMP", os);
				os.close();
				// ImageIO.write(tag, "JPEG", new File("aa.jpg"));
				return os.toByteArray();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	int[] s0 = new int[] { -1, -1, 0, 0, 0, -1, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1,
			0, -1, 0, -1, -1, -1, -1, 0, -1, 0, 0, -1, -1, -1, 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
	int[] s1 = new int[] { -1, -1, 0, -1, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0,
			-1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
	int[] s2 = new int[] { -1, -1, 0, 0, 0, -1, -1, 0, 0, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1,
			-1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, };
	int[] s3 = new int[] { -1, 0, 0, 0, 0, -1, -1, 0, 0, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1,
			0, -1, -1, -1, -1, -1, -1, 0, -1, 0, 0, -1, -1, -1, 0, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
	int[] s4 = new int[] { -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, 0, -1, -1, 0, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0,
			0, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, };
	int[] s5 = new int[] { 0, 0, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1,
			0, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
	int[] s6 = new int[] { -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1,
			-1, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
	int[] s7 = new int[] { 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1,
			-1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
	int[] s8 = new int[] { -1, 0, 0, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1,
			0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
	int[] s9 = new int[] { -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, 0, 0, -1, -1, -1, 0, -1, -1, 0, 0, 0, 0, 0,
			-1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
	int[] s10 = new int[] { -1, -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1,
			-1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, 0, 0, -1, -1, 0, 0, 0, 0, -1, };
	int[] s11 = new int[] { -1, -1, 0, -1, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0,
			-1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, -1, -1, };
	int[] s12 = new int[] { -1, -1, 0, 0, 0, 0, -1, 0, 0, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0,
			-1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, };
	int[] s13 = new int[] { -1, 0, 0, 0, 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1,
			-1, 0, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, -1, 0, 0, 0, 0, -1, -1, };
	int[] s14 = new int[] { -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0, 0, -1, -1, 0, -1, -1, 0, -1, -1, -1, 0, -1, 0, 0, -1, -1, -1,
			0, -1, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, };
	int[] s15 = new int[] { 0, 0, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, 0, -1, -1, 0, 0, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1,
			-1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, -1, 0, 0, 0, -1, -1, -1, };
	int[] s16 = new int[] { -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1,
			-1, 0, 0, -1, -1, -1, -1, -1, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, 0, 0, -1, 0, 0, 0, 0, 0, -1, };
	int[] s17 = new int[] { 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, -1,
			-1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, };
	int[] s18 = new int[] { -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, -1, -1, 0, 0, 0, 0,
			-1, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, -1, -1, -1, 0, 0, -1, 0, 0, 0, 0, 0, -1, };
	int[] s19 = new int[] { -1, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, -1, -1, 0, 0, 0, 0,
			-1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, 0, 0, -1, -1, -1, -1, };

}
